基于 Docker 的哪吒探针多合一部署方案

Agent-Dockerapp.py:基于 Docker 的哪吒探针多合一部署方案

一直想在云服务器上部署一个监控探针,但又不想占用太多资源? 这是一个基于 Docker 的哪吒探针持久化部署方案。 这个项目可以将哪吒探针部署在各类免费或付费的容器托管平台(如 Koyeb, Claw Cloud, Render, Zeabur 等),充分利用资源。

访问此项目的Github地址

项目简介

Agent-Dockerapp.py 是一个轻量级的解决方案,旨在简化哪吒探针的部署流程。 它通过 Docker 容器化技术,将探针及其依赖项打包成一个独立的单元,从而实现快速、便捷的部署和管理。

这个方案内置了 Flask 伪装页面 🎭 和多探针支持 🚀,可以在一个免费服务中高效、稳定地运行多个探针。

项目特性

  • 容器化部署: 基于 Dockerfile 构建,方便迁移和部署。
  • 多探针支持: 在一个服务实例中,通过环境变量即可同时运行多个探针,节省资源。
  • 网页伪装: 内置一个基于 Flask 的精美伪装页面,有效应对部分平台的闲置策略和审查,避免服务被意外停止。
  • 自动构建: 集成 GitHub Actions,每次更新代码后会自动构建最新的 Docker 镜像并推送到 GitHub Packages (GHCR),保持镜像最新。
  • 平台通用: 适用于任何支持从公开 Docker 镜像部署的平台,具有良好的兼容性。

核心代码解析

下面我们来深入了解一下 Agent-Dockerapp.py 的核心代码:

  • app.py: 这是项目的核心文件,包含 Flask 应用和探针启动逻辑。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    import os
    import subprocess
    import threading
    import platform
    import logging
    from flask import Flask, render_template_string

    # --- 标准日志设置 ---
    logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - [CoreService] %(message)s')

    NZ_SERVER = os.environ.get('NZ_SERVER')
    NZ_CLIENT_SECRET = os.environ.get('NZ_CLIENT_SECRET')
    NZ_TLS = os.environ.get('NZ_TLS', 'false')

    # --- 后台核心组件启动逻辑 ---
    def run_background_service():
    if not NZ_SERVER or not NZ_CLIENT_SECRET:
    logging.error("环境变量不完整,后台核心服务无法启动。")
    return

    disguised_executable = './service_worker'

    if not os.path.exists(disguised_executable):
    logging.info("未找到核心组件,开始进行初始化安装...")
    try:
    arch_map = {'x86_64': 'amd64', 'aarch64': 'arm64'}
    machine_arch = platform.machine()
    nezha_arch = arch_map.get(machine_arch)
    if not nezha_arch:
    logging.error(f"不支持的 CPU 架构: {machine_arch}")
    return

    zip_name = f"component_{nezha_arch}.zip"
    download_url = f"https://github.com/nezhahq/agent/releases/latest/download/nezha-agent_linux_{nezha_arch}.zip"

    logging.info(f"正在从远程仓库下载组件...")
    subprocess.run(['curl', '-L', download_url, '-o', zip_name], check=True)
    logging.info(f"正在解压组件...")
    subprocess.run(['unzip', '-o', zip_name, '-d', '.'], check=True)

    os.rename('./nezha-agent', disguised_executable)
    os.chmod(disguised_executable, 0o755)
    os.remove(zip_name)
    logging.info("核心组件初始化成功。")
    except Exception as e:
    logging.error(f"核心组件初始化过程中发生错误: {e}")
    return

    logging.info("准备启动后台核心服务...")
    try:
    agent_env = os.environ.copy()
    command = [disguised_executable]
    agent_process = subprocess.Popen(command, env=agent_env)
    logging.info(f"后台核心服务已启动,进程ID: {agent_process.pid}")
    except Exception as e:
    logging.error(f"启动后台核心服务时发生错误: {e}")

    # --- 创建Flask应用作为伪装 ---
    app = Flask(__name__)

    LUO_TIANYI_HTML = """
    <!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>洛天依 - 官方宣传页</title><style>body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji';background-color:#eef2f9;color:#333;margin:0;display:flex;justify-content:center;align-items:center;min-height:100vh;text-align:center}.container{background:white;padding:2rem;border-radius:16px;box-shadow:0 10px 25px rgba(0,0,0,.1);max-width:600px;margin:20px;transition:transform .3s ease}.container:hover{transform:translateY(-5px)}img{max-width:100%;height:auto;border-radius:12px;margin-top:1.5rem}h1{color:#4a90e2;font-size:2.5rem;margin-bottom:.5rem}p{font-size:1.1rem;line-height:1.6;color:#555}small{color:#999;margin-top:2rem;display:inline-block}</style></head><body><div class="container"><h1>洛天依 (Luo Tianyi)</h1><p>一位能够凭借感情的共鸣,将听众内心的“感动”化为歌声的虚拟歌手。</p><img src="https://res.vsinger.com/images/5836136cca1d92376a95ca356dfeb2d7.png?x-oss-process=image/resize,w_400" alt="洛天依官方图片"><small>This is a fan-made page for demonstration.</small></div></body></html>
    """

    @app.route('/')
    def home():
    return render_template_string(LUO_TIANYI_HTML)

    # --- 启动后台探针 ---
    # 在Flask启动前,先在后台线程中启动探针
    service_thread = threading.Thread(target=run_background_service)
    service_thread.daemon = True
    service_thread.start()

    这段代码主要做了以下几件事:

    • 读取环境变量: 从环境变量中获取哪吒探针的配置信息,例如服务器地址 NZ_SERVER 和客户端密钥 NZ_CLIENT_SECRET
    • 下载和安装探针: 如果在容器中没有找到探针的可执行文件,则从 GitHub Releases 下载对应架构的探针,并进行解压和安装。
    • 启动探针: 在后台线程中启动哪吒探针进程,确保探针可以持续运行。
    • Flask 伪装页面: 创建一个简单的 Flask 应用,返回一个伪装的 HTML 页面,避免因为服务长时间空闲而被平台停止。
  • Dockerfile: 定义了 Docker 镜像的构建过程。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    FROM python:3.9-slim-buster

    WORKDIR /app

    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt

    COPY . .

    CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

    这个 Dockerfile 使用 Python 3.9 作为基础镜像,安装 Flask 和其他依赖项,并将项目代码复制到容器中。最后,使用 gunicorn 启动 Flask 应用。

  • .github/workflows/docker-build.yml: 定义了 GitHub Actions 的构建流程。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    # GitHub Action: Build and Push Docker image to GHCR
    name: Build and Push Docker Image

    # 当有代码推送到 main 分支时,自动触发此流程
    on:
    push:
    branches: [ "main" ]

    jobs:
    build-and-push:
    runs-on: ubuntu-latest

    permissions:
    contents: read
    packages: write

    steps:
    # 检出代码
    - name: Checkout repository
    uses: actions/checkout@v4

    # 将仓库路径转换为全小写,并设置为环境变量
    - name: Set repository name to lowercase
    run: echo "REPO_LC=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV

    # 登录到GitHub容器镜像仓库(GHCR)
    - name: Log in to the Container registry
    uses: docker/login-action@v3
    with:
    registry: ghcr.io
    username: ${{ github.actor }}
    password: ${{ secrets.GITHUB_TOKEN }}

    # 构建Docker镜像并推送
    - name: Build and push Docker image
    uses: docker/build-push-action@v5
    with:
    context: .
    push: true
    tags: ghcr.io/${{ env.REPO_LC }}:latest

    这个 YAML 文件定义了一个 GitHub Actions Workflow,当 main 分支有代码提交时,会自动构建 Docker 镜像并推送到 GitHub Packages (GHCR)。

部署教程

  1. 准备工作: 注册一个容器托管平台账号(如 Koyeb, Claw Cloud, Render, Zeabur 等)。

  2. 登录容器平台。

  3. 创建一个新应用,选择从公开镜像 (Public Image) 部署。

  4. 在镜像地址输入框中,完整粘贴镜像地址 ghcr.io/sparklewink/agent-docker:latest

  5. 配置环境变量: 根据平台的提示,在环境变量设置中添加哪吒探针的配置信息,例如 NZ_SERVER, NZ_CLIENT_SECRET 等。 参考表格如下:

    探针 #1 (必需)

    变量名 示例值 描述 📝
    NZ_SERVER agent.lty.qzz.io:8080 哪吒面板服务器地址和端口。
    NZ_CLIENT_SECRET CN19491001 哪吒面板探针密钥。
    NZ_TLS false 是否启用 TLS/SSL ( truefalse )。

    探针 #2 (可选)

    如果想在同一个服务中运行第二个探针,请添加以下变量:

    变量名 描述 📝
    NZ_SERVER_2 第二个探针的服务器地址和端口。
    NZ_CLIENT_SECRET_2 第二个探针的密钥。
    NZ_TLS_2 第二个探针是否启用 TLS。

    💡 提示: 可以按照 _3, _4 的规律,继续添加更多探针的变量(需稍微修改 app.py 脚本以支持)。

  6. 选择免费套餐并点击 “部署”。

注意事项

  • 镜像可见性: 请确保 GitHub Packages 中的 Docker 镜像 (ghcr.io/sparklewink/agent-docker:latest) 设置为 **”Public” (公开)**,外部平台才能成功拉取。
  • 自动更新: 每当 main 分支有新的代码提交时,GitHub Actions 都会自动构建一个 :latest 标签的新镜像。 如果想应用更新,只需在云平台上触发一次“重新部署(Redeploy)”即可。

总结

Agent-Dockerapp.py 是一个简单易用、功能强大的哪吒探针部署方案。 它通过 Docker 容器化技术,简化了部署流程,并提供了多探针支持和网页伪装等实用功能。 如果你想在云服务器上部署哪吒探针,不妨试试这个项目!


声明: 本博客文章中如有任何涉及版权的内容,请立即联系 admin@main.712521.xyz,我们将尽快处理。